package com.zxq.demo.admin.thread;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.zxq.demo.admin.helper.JobHelper;
import com.zxq.demo.admin.init.ZxqJobConfig;
import com.zxq.demo.admin.model.ZxqJobInfo;
import org.quartz.CronExpression;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author zw
 * @description
 * @email 2408003640@qq.com
 * @date 2025/6/15 21:41
 */
public class TriggerJobThread extends Thread{

    private static final Logger log = LoggerFactory.getLogger(TriggerJobThread.class);

    @Override
    public void run() {
        while (true) {
            try {
                List<ZxqJobInfo> jobInfoList = ZxqJobConfig.getJobInfoList();
                if (CollectionUtil.isEmpty(jobInfoList)) {
                    // 没有任务, 休眠100毫秒
                    Thread.sleep(100);
                    continue;
                }
                long nowTime = System.currentTimeMillis();
                for (ZxqJobInfo jobInfo : jobInfoList) {
                    if (Objects.nonNull(jobInfo.getTriggerNextTime()) &&
                            0l != jobInfo.getTriggerNextTime() && nowTime > jobInfo.getTriggerNextTime()) {
                        // 触发任务之后更新下次执行时间
                        new Thread(() -> {
                            JobHelper.triggerJobById(jobInfo.getId());
                        }).start();
                        jobInfo.setTriggerNextTime(getNextValidTime(jobInfo.getScheduleConf(), nowTime));
                        ZxqJobConfig.updateJobInfo(jobInfo);
                    } else {
                        long nextTime = getNextValidTime(jobInfo.getScheduleConf(), nowTime);
                        // 如果下次执行时间与当前计算出的执行时间不同，也要更新下次执行时间
                        if (nextTime != jobInfo.getTriggerNextTime()) {
                            jobInfo.setTriggerNextTime(nextTime);
                            ZxqJobConfig.updateJobInfo(jobInfo);
                        }
                    }
                }
                Thread.sleep(100);
            } catch (Exception e) {
                log.error("定时任务触发器异常, 异常信息: {}", e.getMessage());
                e.printStackTrace();
            }
        }
    }
    public static long getNextValidTime(String cron, long startTime) {
        try {
            CronExpression cronExpression = new CronExpression(cron);
            return cronExpression.getNextValidTimeAfter(new Date(startTime)).getTime();
        } catch (ParseException e) {
            throw new IllegalArgumentException("Invalid cron expression: " + cron, e);
        }
    }
}
